package com.mallcai.bigdata.ladon.service.report.impl.handler.support;

import com.mallcai.bigdata.ladon.dpl.vo.DataType;
import com.mallcai.bigdata.ladon.utils.CollectionUtils;
import com.mallcai.bigdata.ladon.utils.DateUtils;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author feixy
 * @version 1.0
 * @date 2019-07-20 17:02
 */
public class ParamValueConverter {

    /**
     * 转换参数
     * @param value
     * @param dataType
     * @param isMulti :是否多选字段
     * @return
     */
    public static Object convert(String value, DataType dataType, boolean isMulti) {
        Object ans;
        if(isMulti && value != null){
            String[] split = StringUtils.split(value.trim(), ",");
            ans =  Arrays.stream(split).map(val-> convertSingleValue(val.trim(), dataType)).collect(Collectors.toList());
        } else {
            ans = convertSingleValue(value, dataType);
        }
        return ans;
    }

    /**
     *
     * @param value
     * @param dataType
     * @return
     */
    public static Object convertSingleValue(String value, DataType dataType){
        if(value == null){
            return null;
        }
        value = value.trim();
        Object ans = value;
        if(dataType == DataType.INTEGER){
            ans = getNumberValue(value, Double::intValue);
        } else if (dataType == DataType.LONG){
            ans =  getNumberValue(value, Double::longValue);
        } else if (dataType == DataType.FLOAT){
            ans =  getNumberValue(value, Double::floatValue);
        } else if (dataType == DataType.DOUBLE){
            ans = getNumberValue(value, Double::valueOf);
        } else if (dataType == DataType.DATETIME){
            ans =  DateUtils.parseDate(value, DateUtils.NORMAL_DATE_FORMAT);
        } else if (dataType == DataType.DATE){
            ans =  DateUtils.parseDate(value, DateUtils.DATE_FORMAT_DATE);
        } else if (dataType == DataType.BOOLEAN){
            ans =  StringUtils.isEmpty(value) ? null : Boolean.valueOf(value);
        }
        return ans;
    }


    /**
     * 将object类型的值尝试转化为指定的数据类型,如果转换错误,则会报错
     * @param obj
     * @param dataType
     * @return
     */
    public static Object convertIfNecessary(Object obj, DataType dataType) {

        if (obj == null) {
            return null;
        }
        if (CollectionUtils.isCollection(obj)){
           return ((Collection)obj).stream().map(o-> convertIfNecessary(o, dataType)).collect(Collectors.toList());
        }
        Object ans = obj;
        if(dataType == DataType.INTEGER){
            if(obj.getClass() == BigDecimal.class){
                ans = ((BigDecimal)obj).intValue();
            } else if(obj.getClass() != Integer.class && obj.getClass() != int.class){
                ans = convertSingleValue(obj.toString(), dataType);
            }
        } else if (dataType == DataType.LONG){
            if(obj.getClass() == BigDecimal.class){
                ans = ((BigDecimal)obj).longValue();
            } else if(obj.getClass() != Long.class && obj.getClass() != long.class){
                ans = convertSingleValue(obj.toString(), dataType);
            }
        } else if (dataType == DataType.FLOAT){
            if(obj.getClass() == BigDecimal.class){
                ans = ((BigDecimal)obj).floatValue();
            } if(obj.getClass() != Float.class && obj.getClass() != float.class){
                ans = convertSingleValue(obj.toString(), dataType);
            }
        } else if (dataType == DataType.DOUBLE){
            if(obj.getClass() == Double.class){
                ans = ((BigDecimal)obj).doubleValue();
            } if(obj.getClass() != Double.class && obj.getClass() != double.class){
                ans = convertSingleValue(obj.toString(), dataType);
            }
        } else if (dataType == DataType.DATETIME || dataType == DataType.DATE){
            if(obj.getClass() != Date.class){
                ans = convertSingleValue(obj.toString(), dataType);
            }
        } else if (dataType == DataType.BOOLEAN){
            if(obj.getClass() != Boolean.class){
                ans = convertSingleValue(obj.toString(), dataType);
            }
        }
        return ans;

    }


    private static <T> T getNumberValue(String value, Function<Double,T> mapper){
        return StringUtils.isEmpty(value) ? null : mapper.apply(Double.valueOf(value));
    }

}
